﻿using NetworkCommsDotNet.Connections;
using NetWorkTcpLibrary;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Net;
using System.Net.Sockets;
using System.Windows.Forms;

namespace WinFrom_TcpServer
{
    public partial class Server_Form : Form
    {
        /// <summary>
        /// 服务端类库对象
        /// </summary>
        private NetWorkTcpServer netWorkTcpServer;

        /// <summary>
        /// 监听启动状态
        /// </summary>
        private bool ListenStatus = false;

        public Server_Form()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //获取本机的网卡IP
            string name = Dns.GetHostName();
            IPAddress[] ipadrlist = Dns.GetHostAddresses(name);
            foreach (IPAddress ipa in ipadrlist)
            {
                if (ipa.AddressFamily == AddressFamily.InterNetwork)
                {
                    comboBox_IP.Items.Add(ipa.ToString());
                }
            }
            //默认选中最后一个
            if (comboBox_IP.Items.Count > 0)
            {
                comboBox_IP.SelectedIndex = comboBox_IP.Items.Count - 1;
            }
        }

        private void button_Startlisten_Click(object sender, EventArgs e)
        {
            try
            {
                if (ListenStatus)
                {
                    netWorkTcpServer.StopServerListening();//停止监听
                    netWorkTcpServer.EventChangeOnlineCount -= NetWorkTcpServer_ChangeOnlineCountAction;//连接数变化事件
                    netWorkTcpServer.EventOffLine -= NetWorkTcpServer_EventOffLine;//下线事件
                    netWorkTcpServer.EventOnLine -= NetWorkTcpServer_EventOnLine;//上线事件
                    netWorkTcpServer.MessgeObjHandle -= NetWorkTcpServer_MessgeHandle;//消息处理事件(对象)
                    netWorkTcpServer.ReturnMessgeObjHandle -= NetWorkTcpServer_ReturnMessgeHandle;//需要返回的消息处理事件（对象）
                    netWorkTcpServer.MessgeStrHandle -= NetWorkTcpServer_MessgeStrHandle;//消息处理事件(字符串)
                    netWorkTcpServer.ReturnMessgeStrHandle -= NetWorkTcpServer_ReturnMessgeStrHandle;//需要返回的消息处理事件（字符串）
                    button_Startlisten.Text = "创建监听";
                    listBox_OnlineList.Items.Clear();
                    button_Startlisten.BackColor = Color.Red;
                    ListenStatus = !ListenStatus;
                }
                else
                {
                    netWorkTcpServer = new NetWorkTcpServer("ReceiveObjName", "ReturnObjName","ReceiveStrName","ReturnStrName");//初始化类库
                    netWorkTcpServer?.StartListening($"{comboBox_IP.Text}:{textBox_Port.Text}");//开始监听
                    netWorkTcpServer.EventChangeOnlineCount += NetWorkTcpServer_ChangeOnlineCountAction;//连接数变化事件
                    netWorkTcpServer.EventOffLine += NetWorkTcpServer_EventOffLine;//下线事件
                    netWorkTcpServer.EventOnLine += NetWorkTcpServer_EventOnLine;//上线事件
                    netWorkTcpServer.MessgeObjHandle += NetWorkTcpServer_MessgeHandle;//消息处理事件(对象)
                    netWorkTcpServer.ReturnMessgeObjHandle += NetWorkTcpServer_ReturnMessgeHandle;//需要返回的消息处理事件（对象）
                    netWorkTcpServer.MessgeStrHandle += NetWorkTcpServer_MessgeStrHandle;//消息处理事件(字符串)
                    netWorkTcpServer.ReturnMessgeStrHandle += NetWorkTcpServer_ReturnMessgeStrHandle;//需要返回的消息处理事件（字符串）
                    button_Startlisten.Text = "监听成功";
                    button_Startlisten.BackColor = Color.Green;
                    ListenStatus = !ListenStatus;
                }
            }
            catch (Exception ex)
            {
                richTextBox_Messge.AppendText($"\n{ex.Message}");
            }
        }
        /// <summary>
        /// 需要返回的消息处理事件（字符串）
        /// </summary>
        /// <param name="arg1"></param>
        /// <param name="arg2"></param>
        private void NetWorkTcpServer_ReturnMessgeStrHandle(Connection conn, string arg2)
        {
            Invoke(new Action(() =>
            {
                richTextBox_Messge.AppendText($"\n收到客户端{conn.ConnectionInfo.RemoteEndPoint}的消息-->{arg2}");
            }));
            conn.SendObject<string>("ReturnStrng", $"服务端{conn.ConnectionInfo.LocalEndPoint}收到消息-->x:{arg2}");
        }

        /// <summary>
        /// 消息处理事件(字符串)
        /// </summary>
        /// <param name="arg1"></param>
        /// <param name="arg2"></param>
        private void NetWorkTcpServer_MessgeStrHandle(Connection arg1, string arg2)
        {
            Invoke(new Action(() =>
            {
                richTextBox_Messge.AppendText($"\n收到客户端{arg1.ConnectionInfo.RemoteEndPoint}的消息-->x:{arg2}");
            }));
        }

        /// <summary>
        /// 需要返回的消息处理事件
        /// </summary>
        /// <param name="conn"></param>
        /// <param name="arg2"></param>
        private void NetWorkTcpServer_ReturnMessgeHandle(NetworkCommsDotNet.Connections.Connection conn, XYZ arg2)
        {
            Invoke(new Action(() =>
            {
                richTextBox_Messge.AppendText($"\n收到客户端{conn.ConnectionInfo.RemoteEndPoint}的消息-->x:{arg2._X},y:{arg2._Y},z:{arg2._Z}");
            }));
            conn.SendObject<string>("ReturnStrng", $"服务端{conn.ConnectionInfo.LocalEndPoint}收到消息-->x:{arg2._X},y:{arg2._Y},z:{arg2._Z}");
        }

        /// <summary>
        /// 消息处理事件
        /// </summary>
        /// <param name="arg1"></param>
        /// <param name="arg2"></param>
        private void NetWorkTcpServer_MessgeHandle(NetworkCommsDotNet.Connections.Connection arg1, XYZ arg2)
        {
            Invoke(new Action(() =>
            {
                richTextBox_Messge.AppendText($"\n收到客户端{arg1.ConnectionInfo.RemoteEndPoint}的消息-->x:{arg2._X},y:{arg2._Y},z:{arg2._Z}");
            }));
        }

        /// <summary>
        /// 上线事件
        /// </summary>
        /// <param name="obj"></param>
        private void NetWorkTcpServer_EventOnLine(NetworkCommsDotNet.ConnectionInfo obj)
        {
            this.Invoke(new Action(() =>
            {
                var ip = obj.RemoteEndPoint.ToString();

                //客户端上线添加到列表显示
                if (listBox_OnlineList.Items.IndexOf(ip) == -1)
                {
                    listBox_OnlineList.Items.Add(ip);
                }
            }));
        }

        /// <summary>
        /// 下线事件
        /// </summary>
        /// <param name="obj"></param>
        private void NetWorkTcpServer_EventOffLine(NetworkCommsDotNet.ConnectionInfo obj)
        {
            this.Invoke(new Action(() =>
            {
                //客户端离线
                listBox_OnlineList.Items.Remove(obj.RemoteEndPoint.ToString());
            }));
        }

        /// <summary>
        /// 连接数变化事件
        /// </summary>
        /// <param name="OnlineCount"></param>
        private void NetWorkTcpServer_ChangeOnlineCountAction(int OnlineCount)
        {
            Invoke(new Action(() =>
            {
                label_OnlineCount.Text = $"在线连接数:{OnlineCount}";
            }));
        }

        /// <summary>
        /// 双击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void richTextBox_Messge_DoubleClick(object sender, EventArgs e)
        {
            richTextBox_Messge.Clear();
        }

        /// <summary>
        /// 端口输入框只允许输入数字
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void textBox_Port_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar != 8 && !Char.IsDigit(e.KeyChar))
            {
                e.Handled = true;
            }
        }

        /// <summary>
        /// 发送消息测试菜单绑定
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void listBox_OnlineList_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)

            {
                if (listBox_OnlineList.SelectedValue != null)//空白处不弹出右键菜单
                {
                    contextMenuStrip1.Show(listBox_OnlineList, new Point(e.X, e.Y));
                }
            }
        }

        private void 给选中连接发送测试数据ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            List<Connection> connections = netWorkTcpServer.GetConnections();
            XYZ xYZ = new XYZ();
            Random random = new Random();
            xYZ._X = random.Next(0, 1000);
            xYZ._Y = random.Next(0, 1000);
            xYZ._Z = random.Next(0, 1000);
            foreach (string row in listBox_OnlineList.SelectedItems)
            {
                foreach (Connection connection in connections)
                {
                    if (connection.ConnectionInfo.RemoteEndPoint.ToString() == row)
                    {
                        connection.SendObject<XYZ>("ServerTest", xYZ);
                        break;
                    }
                }
            }
        }

        private void 群发测试数据ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            List<Connection> connections = netWorkTcpServer.GetConnections();
            XYZ xYZ = new XYZ();
            Random random = new Random();
            xYZ._X = random.Next(0, 1000);
            xYZ._Y = random.Next(0, 1000);
            xYZ._Z = random.Next(0, 1000);
            foreach (Connection connection in connections)
            {
                connection.SendObject<XYZ>("ServerTest", xYZ);
            }
        }
    }
}